﻿package mortal.game.scene3D.map3D.AstarAnyDirection
{
    import Message.Public.*;
    import __AS3__.vec.*;
    import flash.geom.*;
    import flash.utils.*;
    import mortal.game.*;
    import mortal.game.scene3D.map3D.*;
    import mortal.game.scene3D.map3D.AstarAnyDirection.data.*;
    import mortal.game.scene3D.map3D.AstarAnyDirection.processor.*;
    import mortal.game.scene3D.map3D.util.*;

    public class AstarAnyDirection extends Object
    {
        private static var nowversion:int = 0;
        private static var _start:AstarIIPoint;
        public static var _end:AstarIIPoint;
        private static var _RectEnd:Point = new Point();
        private static var _rectStart:Point = new Point();
        private static var _mapData:Array;
        private static var _v:Vector.<AstarIIPoint>;
        private static var v1:Vector2f = new Vector2f();
        private static var v2:Vector2f = new Vector2f();
        private static var v3:Vector2f = new Vector2f();
        private static var v4:Vector2f = new Vector2f();
        private static var _diagCost:Number = 1;
        private static var _straightCost:Number = 1.414;

        public function AstarAnyDirection()
        {
            return;
        }// end function

        public static function addSharp(param1:SMapSharp, param2:Boolean = true, param3:Array = null) : void
        {
            var _loc_5:SPoint = null;
            var _loc_6:Point = null;
            var _loc_4:* = param1.points;
            for each (_loc_5 in _loc_4)
            {
                
                _loc_6 = GameMapUtil.getTilePoint(_loc_5.x, _loc_5.y);
                if (param2)
                {
                    _mapData[_loc_6.x][_loc_6.y] = 0;
                    continue;
                }
                _mapData[_loc_6.x][_loc_6.y] = param3[_loc_6.x][_loc_6.y];
            }
            resetLink(true, true);
            return;
        }// end function

        public static function addBossSharp(param1:Dictionary) : void
        {
            var _loc_2:* = undefined;
            var _loc_3:SPoint = null;
            var _loc_4:Boolean = false;
            if (_mapData == null)
            {
                return;
            }
            for (_loc_2 in param1)
            {
                
                _loc_3 = _loc_2 as SPoint;
                _loc_4 = param1[_loc_3];
                if (_loc_4)
                {
                    _mapData[_loc_3.x][_loc_3.y] = -1;
                    continue;
                }
                _mapData[_loc_3.x][_loc_3.y] = 1;
            }
            resetLink(true, true);
            return;
        }// end function

        public static function copyMapData(param1:Array) : void
        {
            var _loc_3:Array = null;
            var _loc_4:Array = null;
            var _loc_5:int = 0;
            _mapData = [];
            var _loc_2:int = 0;
            while (_loc_2 < param1.length)
            {
                
                _loc_3 = param1[_loc_2];
                _loc_4 = [];
                _loc_5 = 0;
                while (_loc_5 < _loc_3.length)
                {
                    
                    _loc_4[_loc_5] = _loc_3[_loc_5];
                    _loc_5++;
                }
                _mapData[_loc_2] = _loc_4;
                _loc_2++;
            }
            return;
        }// end function

        public static function get mapData() : Array
        {
            return _mapData;
        }// end function

        public static function findPath(param1:int, param2:int, param3:int, param4:int, param5:Boolean, param6:Boolean = false) : Array
        {
            var _loc_8:int = 0;
            var _loc_9:int = 0;
            var _loc_10:AstarIILink = null;
            var _loc_11:AstarIILink = null;
            var _loc_12:AstarIIPoint = null;
            var _loc_13:AstarIIPoint = null;
            var _loc_14:AstarIIPoint = null;
            var _loc_27:Number = NaN;
            var _loc_28:AstarTurnPoint = null;
            var _loc_29:AstarTurnPoint = null;
            var _loc_30:AstarTurnPoint = null;
            var _loc_7:* = getTimer();
            if (_mapData == null)
            {
                return [];
            }
            resetLink(param5);
            var _loc_32:* = nowversion + 1;
            nowversion = _loc_32;
            var _loc_15:* = new Point();
            var _loc_16:* = new Point();
            var _loc_17:Number = 0;
            var _loc_18:Number = 0;
            var _loc_19:Number = 0;
            var _loc_20:* = new BinaryHeap(justMin);
            _start = calcNearestPoint(param1, param2, _v);
            _rectStart = _RectEnd;
            _RectEnd = new Point();
            _end = calcNearestPoint(param3, param4, _v);
            _loc_13 = _start;
            _loc_13.version = nowversion;
            var _loc_21:* = new Point(_rectStart.x, _rectStart.y);
            _loc_13.inX = _loc_21.x;
            _loc_13.inY = _loc_21.y;
            var _loc_22:* = new Point();
            while (_loc_13 != _end)
            {
                
                if (_loc_13.links == null)
                {
                    return [];
                }
                _loc_8 = _loc_13.links.length;
                _loc_12 = _loc_13.parent;
                _loc_21.x = _loc_13.inX;
                _loc_21.y = _loc_13.inY;
                if (_loc_13.linkTM >= 0 && _loc_12 != null)
                {
                    _loc_11 = _loc_12.links[_loc_13.linkTM];
                }
                _loc_9 = 0;
                while (_loc_9 < _loc_8)
                {
                    
                    _loc_10 = _loc_13.links[_loc_9];
                    _loc_14 = _loc_10.otherNode;
                    if (_loc_14 == _loc_12)
                    {
                    }
                    else
                    {
                        _loc_27 = 0;
                        if (_loc_10.isJumpLink)
                        {
                            _loc_17 = _loc_13.g + 1;
                            _loc_22.x = _loc_14.col;
                            _loc_22.y = _loc_14.row;
                            _loc_18 = heuristic(_loc_22, _RectEnd);
                            _loc_19 = _loc_17 + _loc_18;
                        }
                        else
                        {
                            _loc_27 = _loc_10.calcDistance(_loc_21, _RectEnd, _loc_15, _loc_16, _loc_22);
                            _loc_17 = _loc_13.g + _loc_27;
                            _loc_18 = heuristic(_loc_22, _RectEnd);
                            _loc_19 = _loc_17 + _loc_18;
                        }
                        if (_loc_14.version == nowversion)
                        {
                            if (_loc_14.f > _loc_19 + 1e-005)
                            {
                                _loc_14.f = _loc_19;
                                _loc_14.g = _loc_17;
                                _loc_14.h = _loc_18;
                                _loc_14.linkTM = _loc_9;
                                _loc_14.parent = _loc_13;
                                _loc_14.inX = _loc_22.x;
                                _loc_14.inY = _loc_22.y;
                            }
                        }
                        else
                        {
                            _loc_14.f = _loc_19;
                            _loc_14.g = _loc_17;
                            _loc_14.h = _loc_18;
                            _loc_14.parent = _loc_13;
                            _loc_14.linkTM = _loc_9;
                            _loc_20.ins(_loc_14);
                            _loc_14.version = nowversion;
                            _loc_14.inX = _loc_22.x;
                            _loc_14.inY = _loc_22.y;
                        }
                    }
                    _loc_9++;
                }
                if (_loc_20.a.length == 1)
                {
                    return null;
                }
                _loc_13 = _loc_20.pop() as AstarIIPoint;
            }
            var _loc_23:* = buildCommonLines();
            var _loc_24:* = MapGridTurnPointMaker.work(_loc_23, _rectStart, _RectEnd);
            var _loc_25:Array = [];
            if (_loc_24 == null || _loc_24.length == 0)
            {
                return _loc_25;
            }
            var _loc_26:Array = [];
            _loc_9 = 0;
            while (_loc_9 < _loc_24.length)
            {
                
                _loc_28 = _loc_24[_loc_9];
                if (_loc_28.isJump)
                {
                    _loc_29 = new AstarTurnPoint();
                    _loc_29._x = _loc_28._x;
                    _loc_29._y = _loc_28._y;
                    _loc_29.distance = _loc_28.distance;
                    _loc_29.parent = _loc_28.parent;
                    _loc_29.value = _loc_28.value;
                    _loc_26.push(_loc_29);
                    _loc_30 = _loc_26[0];
                    _loc_30.parent = null;
                    _loc_28.parent = null;
                    _loc_26 = MapGridTurnPointFixer.fix(_mapData, _loc_26, 5);
                    _loc_25.push(_loc_26);
                    _loc_26 = [];
                    _loc_25.push(_loc_28);
                }
                else
                {
                    _loc_26.push(_loc_28);
                    if (_loc_9 == (_loc_24.length - 1) && _loc_26.length > 0)
                    {
                        _loc_30 = _loc_26[0];
                        _loc_30.parent = null;
                        _loc_26 = MapGridTurnPointFixer.fix(_mapData, _loc_26, 5);
                        _loc_25.push(_loc_26);
                    }
                }
                _loc_9++;
            }
            return _loc_25;
        }// end function

        public static function findNearestWalkablePoint(param1:int, param2:int, param3:Boolean = true) : Point
        {
            if (_mapData == null)
            {
                return new Point(0, 0);
            }
            resetLink(param3);
            calcNearestPoint(param1, param2, _v);
            return _RectEnd.clone();
        }// end function

        public static function resetLink(param1:Boolean, param2:Boolean = false) : void
        {
            var _loc_3:int = 0;
            if (param1)
            {
                _loc_3 = MapNodeType.WALK_MIN_VALUE;
            }
            else
            {
                _loc_3 = MapNodeType.FLY_MIN_VALUE;
            }
            AstarCache.instance.setLink(Game.mapInfo.mapId, _mapData, _loc_3, param2);
            _v = AstarCache.instance.getLink(Game.mapInfo.mapId, _loc_3);
            return;
        }// end function

        public static function buildCommonLines() : Array
        {
            var _loc_3:AstarIIPoint = null;
            var _loc_4:AstarIILink = null;
            var _loc_5:AstarIILink = null;
            var _loc_6:AstarIILink = null;
            var _loc_7:AstarIILink = null;
            var _loc_1:Array = [];
            var _loc_2:* = _end;
            while (_loc_2 != _start && _loc_2.parent != null)
            {
                
                _loc_3 = _loc_2.parent;
                _loc_4 = _loc_2.parent.links[_loc_2.linkTM];
                _loc_6 = new AstarIILink();
                _loc_5 = new AstarIILink();
                if (_loc_2.isJump && _loc_2.parent != null && _loc_2.parent.isJump)
                {
                    var _loc_8:* = _loc_4.minCol;
                    _loc_6.maxCol = _loc_4.minCol;
                    _loc_6.minCol = _loc_8;
                    var _loc_8:* = _loc_4.minRow;
                    _loc_6.maxRow = _loc_4.minRow;
                    _loc_6.minRow = _loc_8;
                    _loc_6.isJumpLink = true;
                    _loc_1.unshift(_loc_6);
                    _loc_7 = _loc_6;
                    _loc_2 = _loc_2.parent;
                    continue;
                }
                else if (_loc_2.isJump)
                {
                    var _loc_8:* = _loc_4.minCol;
                    _loc_6.maxCol = _loc_4.minCol;
                    _loc_6.minCol = _loc_8;
                    var _loc_8:* = _loc_4.minRow;
                    _loc_6.maxRow = _loc_4.minRow;
                    _loc_6.minRow = _loc_8;
                    _loc_1.unshift(_loc_6);
                    _loc_7 = _loc_6;
                    _loc_2 = _loc_2.parent;
                    continue;
                }
                if (_loc_4.minCol == _loc_4.maxCol)
                {
                    var _loc_8:* = _loc_4.minRow + 0.5;
                    _loc_5.minRow = _loc_4.minRow + 0.5;
                    _loc_6.minRow = _loc_8;
                    var _loc_8:* = _loc_4.maxRow - 0.5;
                    _loc_5.maxRow = _loc_4.maxRow - 0.5;
                    _loc_6.maxRow = _loc_8;
                    if (_loc_3.col == _loc_4.maxCol + 0.5)
                    {
                        var _loc_8:* = _loc_4.minCol + 0.5;
                        _loc_6.maxCol = _loc_4.minCol + 0.5;
                        _loc_6.minCol = _loc_8;
                        var _loc_8:* = _loc_4.minCol - 0.5;
                        _loc_5.maxCol = _loc_4.minCol - 0.5;
                        _loc_5.minCol = _loc_8;
                    }
                    else
                    {
                        var _loc_8:* = _loc_4.minCol - 0.5;
                        _loc_6.maxCol = _loc_4.minCol - 0.5;
                        _loc_6.minCol = _loc_8;
                        var _loc_8:* = _loc_4.minCol + 0.5;
                        _loc_5.maxCol = _loc_4.minCol + 0.5;
                        _loc_5.minCol = _loc_8;
                    }
                }
                else
                {
                    var _loc_8:* = _loc_4.minCol + 0.5;
                    _loc_5.minCol = _loc_4.minCol + 0.5;
                    _loc_6.minCol = _loc_8;
                    var _loc_8:* = _loc_4.maxCol - 0.5;
                    _loc_5.maxCol = _loc_4.maxCol - 0.5;
                    _loc_6.maxCol = _loc_8;
                    if (_loc_3.row == _loc_4.maxRow + 0.5)
                    {
                        var _loc_8:* = _loc_4.minRow + 0.5;
                        _loc_6.maxRow = _loc_4.minRow + 0.5;
                        _loc_6.minRow = _loc_8;
                        var _loc_8:* = _loc_4.maxRow - 0.5;
                        _loc_5.maxRow = _loc_4.maxRow - 0.5;
                        _loc_5.minRow = _loc_8;
                    }
                    else
                    {
                        var _loc_8:* = _loc_4.minRow - 0.5;
                        _loc_6.maxRow = _loc_4.minRow - 0.5;
                        _loc_6.minRow = _loc_8;
                        var _loc_8:* = _loc_4.maxRow + 0.5;
                        _loc_5.maxRow = _loc_4.maxRow + 0.5;
                        _loc_5.minRow = _loc_8;
                    }
                }
                if (!isLinkCanDelete(_loc_5, _loc_7, _loc_6))
                {
                    _loc_1.unshift(_loc_5);
                    _loc_7 = _loc_5;
                }
                else
                {
                    _loc_7 = _loc_6;
                }
                _loc_1.unshift(_loc_6);
                _loc_2 = _loc_2.parent;
            }
            return _loc_1;
        }// end function

        private static function isLinkCanDelete(param1:AstarIILink, param2:AstarIILink, param3:AstarIILink) : Boolean
        {
            return false;
        }// end function

        public static function heuristic(param1:Point, param2:Point) : Number
        {
            return GeomUtil.calcDistance(param1.x, param1.y, param2.x, param2.y);
        }// end function

        private static function calcNearestPoint(param1:int, param2:int, param3:Vector.<AstarIIPoint>) : AstarIIPoint
        {
            var _loc_4:AstarIIPoint = null;
            var _loc_6:int = 0;
            var _loc_7:int = 0;
            var _loc_8:int = 0;
            var _loc_9:int = 0;
            var _loc_10:Number = NaN;
            var _loc_11:AstarIIPoint = null;
            var _loc_12:int = 0;
            var _loc_5:Number = 100000000;
            var _loc_13:* = param3.length;
            _loc_12 = 0;
            while (_loc_12 < _loc_13)
            {
                
                _loc_11 = param3[_loc_12];
                if (param1 >= _loc_11.row)
                {
                    if (param1 < _loc_11.endRow)
                    {
                        if (param2 >= _loc_11.col)
                        {
                            if (param2 < _loc_11.endCol)
                            {
                                _RectEnd.x = param2;
                                _RectEnd.y = param1;
                                return _loc_11;
                            }
                        }
                    }
                }
                _loc_12++;
            }
            _loc_12 = 0;
            while (_loc_12 < _loc_13)
            {
                
                _loc_11 = param3[_loc_12];
                _loc_6 = param1 - _loc_11.row;
                _loc_7 = param2 - _loc_11.col;
                _loc_8 = param1 - _loc_11.endRow + 1;
                _loc_9 = param2 - _loc_11.endCol + 1;
                if (param1 < _loc_11.row)
                {
                    if (param2 < _loc_11.col)
                    {
                        _loc_10 = _loc_6 * _loc_6 + _loc_7 * _loc_7;
                        if (_loc_10 < _loc_5)
                        {
                            _loc_5 = _loc_10;
                            _RectEnd.y = _loc_11.row;
                            _RectEnd.x = _loc_11.col;
                            _loc_4 = _loc_11;
                        }
                    }
                    else if (param2 > (_loc_11.endCol - 1))
                    {
                        _loc_10 = _loc_9 * _loc_9 + _loc_6 * _loc_6;
                        if (_loc_10 < _loc_5)
                        {
                            _loc_5 = _loc_10;
                            _RectEnd.y = _loc_11.row;
                            _RectEnd.x = _loc_11.endCol - 1;
                            _loc_4 = _loc_11;
                        }
                    }
                    else
                    {
                        _loc_10 = _loc_6 * _loc_6;
                        if (_loc_10 < _loc_5)
                        {
                            _loc_5 = _loc_10;
                            _RectEnd.y = _loc_11.row;
                            _RectEnd.x = param2;
                            _loc_4 = _loc_11;
                        }
                    }
                }
                else if (param1 > (_loc_11.endRow - 1))
                {
                    if (param2 < _loc_11.col)
                    {
                        _loc_10 = _loc_8 * _loc_8 + _loc_7 * _loc_7;
                        if (_loc_10 < _loc_5)
                        {
                            _loc_5 = _loc_10;
                            _RectEnd.y = _loc_11.endRow - 1;
                            _RectEnd.x = _loc_11.col;
                            _loc_4 = _loc_11;
                        }
                    }
                    else if (param2 > (_loc_11.endCol - 1))
                    {
                        _loc_10 = _loc_8 * _loc_8 + _loc_9 * _loc_9;
                        if (_loc_10 < _loc_5)
                        {
                            _loc_5 = _loc_10;
                            _RectEnd.y = _loc_11.endRow - 1;
                            _RectEnd.x = _loc_11.endCol - 1;
                            _loc_4 = _loc_11;
                        }
                    }
                    else
                    {
                        _loc_10 = _loc_6 * _loc_6;
                        if (_loc_10 < _loc_5)
                        {
                            _loc_5 = _loc_10;
                            _RectEnd.y = _loc_11.endRow - 1;
                            _RectEnd.x = param2;
                            _loc_4 = _loc_11;
                        }
                    }
                }
                else if (param2 <= _loc_11.col)
                {
                    _loc_10 = _loc_7 * _loc_7;
                    if (_loc_10 < _loc_5)
                    {
                        _loc_5 = _loc_10;
                        _RectEnd.y = param1;
                        _RectEnd.x = _loc_11.col;
                        _loc_4 = _loc_11;
                    }
                }
                else
                {
                    _loc_10 = _loc_9 * _loc_9;
                    if (_loc_10 < _loc_5)
                    {
                        _loc_5 = _loc_10;
                        _RectEnd.y = param1;
                        _RectEnd.x = _loc_11.endCol - 1;
                        _loc_4 = _loc_11;
                    }
                }
                _loc_12++;
            }
            return _loc_4;
        }// end function

        private static function justMin(param1:Object, param2:Object) : Boolean
        {
            return param1.f < param2.f;
        }// end function

        public static function isWalkable(param1:int, param2:int) : Boolean
        {
            return MapGridCutter.walkable(mapData[param1][param2]);
        }// end function

        public static function checkIsWalkable(param1:int, param2:int) : Boolean
        {
            if (mapData == null || mapData[param1] == null)
            {
                return false;
            }
            if (mapData[param1][param2] == null)
            {
                return false;
            }
            return MapGridCutter.walkable(mapData[param1][param2]);
        }// end function

        public static function getMaxVisiblePoint(param1:int, param2:int, param3:int, param4:int, param5:Array = null, param6:int = 5) : Point
        {
            var _loc_11:int = 0;
            var _loc_12:int = 0;
            var _loc_13:int = 0;
            if (param5 == null)
            {
                param5 = mapData;
            }
            var _loc_7:* = new Point(param3, param4);
            var _loc_8:* = GeomUtil.calcLinePassGridesFastMidle(param1, param2, param3, param4);
            var _loc_9:int = 0;
            var _loc_10:* = _loc_8.length;
            _loc_9 = 0;
            while (_loc_9 < _loc_10)
            {
                
                _loc_12 = _loc_8[_loc_9];
                _loc_13 = _loc_8[(_loc_9 + 1)];
                if (_loc_12 < 0 || _loc_12 >= GameMapUtil.tileXNum || _loc_13 < 0 || _loc_13 >= GameMapUtil.tileYNum)
                {
                    if (_loc_9 >= 2)
                    {
                        _loc_7.x = _loc_8[_loc_9 - 2];
                        _loc_7.y = _loc_8[(_loc_9 - 1)];
                    }
                    else
                    {
                        _loc_7.x = _loc_12;
                        _loc_7.y = _loc_13;
                    }
                    return _loc_7;
                }
                _loc_11 = param5[_loc_12][_loc_13];
                if (_loc_11 >= 0)
                {
                    if (_loc_11 < param6)
                    {
                        if (_loc_9 >= 2)
                        {
                            _loc_7.x = _loc_8[_loc_9 - 2];
                            _loc_7.y = _loc_8[(_loc_9 - 1)];
                        }
                        else
                        {
                            _loc_7.x = _loc_12;
                            _loc_7.y = _loc_13;
                        }
                        return _loc_7;
                    }
                }
                _loc_9 = _loc_9 + 2;
            }
            return _loc_7;
        }// end function

    }
}

class BinaryHeap extends Object
{
    public var a:Array;
    public var justMinFun:Function;

    function BinaryHeap(param1:Function = null)
    {
        this.a = [];
        this.justMinFun = function (param1:Object, param2:Object) : Boolean
        {
            return param1 < param2;
        }// end function
        ;
        this.a.push(-1);
        if (param1 != null)
        {
            this.justMinFun = param1;
        }
        return;
    }// end function

    public function ins(param1:Object) : void
    {
        var _loc_4:Object = null;
        var _loc_2:* = this.a.length;
        this.a[_loc_2] = param1;
        var _loc_3:* = _loc_2 >> 1;
        while (_loc_2 > 1 && this.justMinFun(this.a[_loc_2], this.a[_loc_3]))
        {
            
            _loc_4 = this.a[_loc_2];
            this.a[_loc_2] = this.a[_loc_3];
            this.a[_loc_3] = _loc_4;
            _loc_2 = _loc_3;
            _loc_3 = _loc_2 >> 1;
        }
        return;
    }// end function

    public function pop() : Object
    {
        var _loc_6:int = 0;
        var _loc_7:Object = null;
        var _loc_1:* = this.a[1];
        this.a[1] = this.a[(this.a.length - 1)];
        this.a.pop();
        var _loc_2:int = 1;
        var _loc_3:* = this.a.length;
        var _loc_4:* = _loc_2 << 1;
        var _loc_5:* = _loc_4 + 1;
        while (_loc_4 < _loc_3)
        {
            
            if (_loc_5 < _loc_3)
            {
                _loc_6 = this.justMinFun(this.a[_loc_5], this.a[_loc_4]) ? (_loc_5) : (_loc_4);
            }
            else
            {
                _loc_6 = _loc_4;
            }
            if (this.justMinFun(this.a[_loc_6], this.a[_loc_2]))
            {
                _loc_7 = this.a[_loc_2];
                this.a[_loc_2] = this.a[_loc_6];
                this.a[_loc_6] = _loc_7;
                _loc_2 = _loc_6;
                _loc_4 = _loc_2 << 1;
                _loc_5 = _loc_4 + 1;
                continue;
            }
            break;
        }
        return _loc_1;
    }// end function

}

